DataStream API এবং DataSet API

Latest Technologies - অ্যাপাচি ফ্লিঙ্ক (Apache Flink) - NCTB BOOK

Apache Flink এ দুটি প্রধান API আছে: DataStream API এবং DataSet API। প্রতিটি API ভিন্ন ভিন্ন কাজের জন্য ব্যবহৃত হয় এবং তাদের আলাদা আলাদা বৈশিষ্ট্য আছে। নিচে এই API দুটি নিয়ে বিস্তারিত আলোচনা করা হলো:

1. DataStream API

DataStream API মূলত streaming ডেটার জন্য ব্যবহৃত হয়, অর্থাৎ এমন ডেটা যা ধারাবাহিকভাবে নিরবচ্ছিন্নভাবে প্রবাহিত হয় (real-time or unbounded data)।

বৈশিষ্ট্যসমূহ:

  • Continuous Data Processing: DataStream API ধারাবাহিক ডেটা প্রসেস করতে পারে। যেমন, সেন্সর ডেটা, লগ, ইভেন্ট স্ট্রিমিং, এবং IoT ডেটা।
  • Time Handling: এটি বিভিন্ন ধরণের টাইম কনসেপ্ট (Processing Time, Event Time) ব্যবহার করে ডেটা প্রসেস করতে পারে।
  • Windowing: DataStream API বিভিন্ন ধরণের উইন্ডো ফাংশন (time-based, count-based) সমর্থন করে, যা স্ট্রিম ডেটাকে ভাগ করার জন্য ব্যবহৃত হয়।
  • Event-Driven: ইভেন্ট-বেসড প্রসেসিং এবং কমপ্লেক্স ইভেন্ট প্রসেসিং (CEP) করা যায়।
  • Fault-Tolerance: Checkpointing এবং state management এর মাধ্যমে স্ট্রিম প্রসেসিং তে ফল্ট-টলারেন্স নিশ্চিত করা হয়।

ব্যবহার:

  • যদি ডেটা রিয়েল-টাইমে আসে এবং তা প্রক্রিয়া করতে হয়, যেমন: লগ প্রসেসিং, ক্লিকস্ট্রিম বিশ্লেষণ, real-time fraud detection, তাহলে DataStream API আদর্শ।

উদাহরণ:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> stream = env.socketTextStream("localhost", 9999);

DataStream<Tuple2<String, Integer>> wordCounts = stream
    .flatMap(new Tokenizer())
    .keyBy(0)
    .sum(1);

wordCounts.print();
env.execute("WordCount Example");

2. DataSet API

DataSet API মূলত batch processing ডেটার জন্য ব্যবহৃত হয়, অর্থাৎ একটি নির্দিষ্ট সময়ে শুরু এবং শেষ হয় এমন ডেটা সেটের জন্য। Flink 1.14 থেকে DataSet API কে ধীরে ধীরে বাদ দেয়া হচ্ছে, এবং এর পরিবর্তে Table API এবং DataStream API ব্যাবহার করার পরামর্শ দেয়া হচ্ছে। তবে এখনও এর কিছু ব্যবহার দেখা যায়।

বৈশিষ্ট্যসমূহ:

  • Batch Processing: DataSet API প্রধানত bounded ডেটা প্রসেসিং এর জন্য ব্যবহৃত হয়। উদাহরণস্বরূপ, একটি ফাইল বা ডাটাবেজ থেকে একটি নির্দিষ্ট ডেটাসেট প্রসেস করা।
  • Transformations: DataSet API বিভিন্ন ধরণের transformation (map, flatMap, filter, reduce) সমর্থন করে।
  • In-Memory Processing: এটি ইন-মেমরি ডেটা প্রসেসিং এর জন্য অপটিমাইজ করা, যা ব্যাচ অপারেশনের পারফরম্যান্স বাড়াতে সাহায্য করে।
  • Iterative Processing: এটি iterative আলগোরিদম (যেমন: machine learning আলগোরিদম) এর জন্য ভালো সমর্থন দেয়।

ব্যবহার:

  • যদি ডেটা স্ট্যাটিক (bounded) হয় এবং সেটির উপর বিভিন্ন ধরনের ব্যাচ অপারেশন করতে হয়, যেমন: ETL প্রসেসিং, রিপোর্ট জেনারেশন, তাহলে DataSet API উপযুক্ত।

উদাহরণ:

ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSet<String> text = env.readTextFile("file:///path/to/data.txt");

DataSet<Tuple2<String, Integer>> counts = text
    .flatMap(new Tokenizer())
    .groupBy(0)
    .sum(1);

counts.print();

DataStream API এবং DataSet API এর পার্থক্য

বৈশিষ্ট্যDataStream APIDataSet API
ডেটা টাইপUnbounded (ধারাবাহিক ডেটা)Bounded (স্থির ডেটা)
টাইম হ্যান্ডলিংEvent Time, Processing Time সাপোর্টটাইম হ্যান্ডলিং নেই
প্রসেসিং টাইপReal-time এবং ContinuousBatch এবং এককালীন প্রসেসিং
উইন্ডো অপারেশনSupportedSupported না
ইটেরেটিভ প্রসেসিংসাপোর্ট করে নাসাপোর্ট করে

উপসংহার

DataStream API এবং DataSet API Flink এ আলাদা উদ্দেশ্যে ব্যবহৃত হয়। বর্তমান সময়ে Flink এর নতুন ভার্সনগুলোতে DataSet API কম ব্যবহৃত হয় এবং Table API এবং DataStream API ব্যবহার বেশি করা হয়, কারণ এগুলো স্ট্রিম এবং ব্যাচ প্রসেসিং উভয়ের জন্যই আরও সমর্থনশীল এবং আধুনিক ফিচার প্রদান করে।

DataStream এবং DataSet এর মধ্যে পার্থক্য

Apache Flink এ DataStream এবং DataSet হলো দুটি আলাদা API যা ভিন্ন ভিন্ন ধরণের ডেটা প্রসেসিংয়ের জন্য ব্যবহৃত হয়। এদের মধ্যে প্রধান পার্থক্যগুলো নিচে দেওয়া হলো:

১. Batch vs. Stream Processing:

  • DataStream API: এটি মূলত স্ট্রিম প্রসেসিং (Real-time Data Processing) এর জন্য ব্যবহৃত হয়, যেখানে ডেটা একটি অবিরাম বা নিরবিচ্ছিন্ন ফ্লো হিসেবে আসে। এটি কোনো নির্দিষ্ট শেষ নেই এবং ডেটা ইনপুট ক্রমাগত পরিবর্তিত হতে থাকে। উদাহরণস্বরূপ, লগ ডেটা প্রসেসিং বা IoT ডিভাইসের সেন্সর ডেটা।
  • DataSet API: এটি মূলত ব্যাচ প্রসেসিং (Batch Processing) এর জন্য ব্যবহৃত হয়, যেখানে একটি নির্দিষ্ট পরিমাণ ডেটা (ফিনাইট ডেটাসেট) নিয়ে কাজ করা হয়। অর্থাৎ, ডেটাসেটের একটি শুরু এবং শেষ আছে। উদাহরণস্বরূপ, একটি নির্দিষ্ট সময়ের মধ্যে সংগৃহীত ট্রানজেকশন ডেটা প্রসেস করা।

২. Time Semantics:

  • DataStream: এখানে টাইমের দুটো মডেল আছে: Event Time এবং Processing Time। ইভেন্ট টাইম হলো ডেটার সাথে সম্পর্কিত আসল সময় (যেমন লগে উল্লেখ করা সময়), আর প্রসেসিং টাইম হলো ডেটা প্রসেস করার সময়।
  • DataSet: এখানে টাইম-বেসড প্রসেসিং এর ধারণা নেই, কারণ এটি একটি ফিক্সড ডেটাসেট নিয়ে কাজ করে যেখানে টাইম ডায়নামিক নয়।

৩. Operators and Transformations:

  • DataStream API: স্ট্রিম প্রসেসিংয়ের জন্য এখানে বিভিন্ন ধরণের অপারেটর এবং ট্রান্সফরমেশন আছে, যেমন window, watermark, join, এবং split। এগুলো মূলত স্ট্রিম ডেটা কন্ট্রোল এবং ফিল্টার করার জন্য ব্যবহৃত হয়।
  • DataSet API: এখানে ব্যাচ প্রসেসিংয়ের জন্য বিভিন্ন ধরণের ট্রান্সফরমেশন রয়েছে, যেমন map, reduce, join, groupBy। এগুলো সাধারণত ব্যাচ ডেটাসেটের উপর বিভিন্ন কম্পিউটেশন চালানোর জন্য ব্যবহৃত হয়।

৪. Fault Tolerance:

  • DataStream: এখানে checkpointing এবং state management এর সুবিধা আছে, যা ফোল্ট টলারেন্স নিশ্চিত করে। ডেটা স্ট্রিমিংয়ের ক্ষেত্রে এটি গুরুত্বপূর্ণ, কারণ প্রসেস চলাকালীন কোনো সমস্যা হলে ডেটা পুনরুদ্ধার করা যায়।
  • DataSet: যেহেতু এটি ব্যাচ প্রসেসিংয়ের জন্য, তাই এখানে স্টেট ম্যানেজমেন্ট এবং চেকপয়েন্টিংয়ের সুবিধা নেই। ব্যাচ ডেটা পুনরায় প্রসেস করা সহজ, কারণ এটি একটি নির্দিষ্ট ডেটাসেট।

৫. Latency:

  • DataStream: এখানে লেটেন্সি সাধারণত অনেক কম, কারণ এটি রিয়েল-টাইম ডেটা প্রসেসিংয়ের জন্য ব্যবহৃত হয়। এটি ইভেন্ট আসার সাথে সাথেই প্রসেস করে।
  • DataSet: ব্যাচ প্রসেসিং হওয়ায় লেটেন্সি সাধারণত একটু বেশি হয়, কারণ পুরো ডেটাসেট প্রস্তুত হলে তবেই প্রসেসিং শুরু হয়।

৬. API Evolution:

  • DataStream API: বর্তমানে Flink এ DataStream API কে আরও উন্নত করা হচ্ছে এবং এটি নতুন স্ট্যান্ডার্ড হয়ে উঠছে। বেশিরভাগ নতুন ফিচার DataStream API তে প্রথমে যুক্ত করা হয়।
  • DataSet API: DataSet API ধীরে ধীরে পুরনো হয়ে যাচ্ছে, এবং ভবিষ্যতে Flink এটিকে DataStream API এর সাথে একীভূত করার পরিকল্পনা করেছে।

সংক্ষেপে:

  • DataStream: স্ট্রিমিং ডেটা, রিয়েল-টাইম প্রসেসিং, লো লেটেন্সি, টাইম-বেসড অপারেশন।
  • DataSet: ব্যাচ ডেটা, নির্দিষ্ট ডেটাসেট, টাইম অপারেশন নেই, প্রসেসিং শেষে ফলাফল পাওয়া যায়।

তাহলে, স্ট্রিম ডেটা প্রসেস করতে হলে DataStream API এবং ব্যাচ ডেটা প্রসেস করতে হলে DataSet API বেছে নেওয়াই সবচেয়ে ভালো।

Streaming এবং Batch Data Processing এর ধারণা

Apache Flink হল একটি distributed stream processing ফ্রেমওয়ার্ক, যা real-time এবং batch data processing দুটোই করতে পারে। এটি high-throughput এবং low-latency ডেটা প্রসেসিং এর জন্য ব্যবহৃত হয়। Flink এর মাধ্যমে আপনি বিশাল আকারের ডেটা সেট বা স্ট্রিম থেকে ইনসাইট পেতে পারেন। Flink এর দুটি প্রাথমিক প্রসেসিং প্যারাডাইম রয়েছে:

1. Streaming Data Processing

Flink মূলত একটি stream processing engine, যা continuous এবং real-time ডেটা প্রসেসিং এর জন্য ডিজাইন করা হয়েছে। Streaming Data Processing এর কিছু বৈশিষ্ট্য:

  • Continuous Data Flow: ডেটা যখনই আসে, তখনই Flink তা প্রক্রিয়া করে। এটি event-driven, অর্থাৎ ডেটা আসার সাথে সাথেই তা প্রক্রিয়া করা হয়।
  • Low-Latency: Flink real-time ডেটা প্রসেসিং এর জন্য কম latency নিশ্চিত করে।
  • Fault-Tolerance: Flink এর streaming engine এর built-in checkpointing এবং state management সিস্টেম আছে, যা সিস্টেমে কোনো সমস্যা হলে (যেমন, নেটওয়ার্ক ফেইলিওর বা হার্ডওয়্যার সমস্যা) পুনরায় শুরু করতে সাহায্য করে।
  • Event Time Processing: Flink event time এবং processing time উভয়ই সমর্থন করে। Event time এর সাহায্যে আপনি historical event গুলো থেকে ডেটা প্রসেস করতে পারেন, যা real-time এর ক্ষেত্রে খুবই গুরুত্বপূর্ণ।

2. Batch Data Processing

Flink batch processing ও সমর্থন করে, যা বিশাল পরিমাণের ডেটা থেকে ইনসাইট পাওয়ার জন্য ব্যবহৃত হয়। যদিও Flink streaming এর জন্য তৈরি, তবে এটি batch ডেটা প্রসেসিং খুব কার্যকরভাবে করতে পারে। Batch Data Processing এর বৈশিষ্ট্যগুলো:

  • Finite Data Sets: Batch প্রসেসিং এ Flink একটি নির্দিষ্ট এবং শেষ হওয়া ডেটা সেট প্রক্রিয়া করে। এটি সাধারণত historical ডেটা বা বড় ফাইল সিস্টেম (যেমন Hadoop HDFS, S3) থেকে ডেটা নিয়ে কাজ করে।
  • Optimized Execution: Flink এর optimizer একটি efficient execution plan তৈরি করে, যা ডেটা প্রক্রিয়াকরণকে দ্রুত এবং কার্যকর করে।
  • Unified API: Flink এর API streaming এবং batch দুই ধরণের ডেটা প্রসেসিং এর জন্য একই থাকে, তাই ডেভেলপাররা একটি কোডবেস দিয়েই দুটি ধরণের ডেটা প্রসেস করতে পারে।

Flink এর Streaming এবং Batch Processing এর পার্থক্য

বিষয়বস্তুStreaming ProcessingBatch Processing
ডেটা প্রবাহContinuous, infinite (অনন্ত) ডেটা প্রবাহFinite (সীমাবদ্ধ) ডেটা সেট
LatencyLow latency, real-timeHigh latency, পুরো ডেটা প্রসেসিং শেষে আউটপুট প্রদান
Fault-ToleranceBuilt-in, নিরবচ্ছিন্ন পুনরায় শুরুRetries বা পুনরায় শুরু প্রয়োজন হতে পারে
Use CaseReal-time analytics, alert systemsHistorical data analysis, batch jobs

Flink এর এই unified architecture (একক স্থাপত্য) স্ট্রিমিং এবং ব্যাচ প্রসেসিং একসাথে ব্যবহারের সুযোগ দেয়, যা Flink কে অত্যন্ত flexible এবং efficient ফ্রেমওয়ার্ক হিসেবে প্রতিষ্ঠিত করেছে।

Flink API-তে তিনটি বেসিক কম্পোনেন্ট আছে: Source, Transformation, এবং Sink। এরা একসাথে ডাটা প্রসেসিং পাইপলাইন তৈরি করে। এই কম্পোনেন্টগুলোকে ব্যাখ্যা করা হলো:

১. Source

Source হলো সেই কম্পোনেন্ট, যা ডাটা স্ট্রিম বা ডাটা ফাইল থেকে ইনপুট হিসেবে ডাটা গ্রহণ করে। এটি ডাটা স্ট্রিমিং শুরু করার জন্য প্রথম ধাপ। Flink API বিভিন্ন ধরণের ইনপুট সোর্স সাপোর্ট করে, যেমন:

  • Kafka: ডাটা স্ট্রিমের জন্য ব্যবহৃত হয়।
  • File System: ফাইল সিস্টেম থেকে ডাটা পড়া যায়।
  • Socket: সোজাসুজি সকেট থেকে ডাটা গ্রহণ করা যায়।
  • Database: বিভিন্ন ডাটাবেস সোর্স থেকে ডাটা ফেচ করা সম্ভব।

Example:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> stream = env.readTextFile("path/to/your/file.txt");

২. Transformation

Transformation হলো সেই প্রক্রিয়া, যা ইনপুট সোর্স থেকে পাওয়া ডাটাকে বিভিন্ন ভাবে প্রক্রিয়াজাত করে আউটপুট হিসেবে তৈরি করে। Transformation-এর মাধ্যমে ডাটা ফিল্টার করা, ম্যাপ করা, গ্রুপ করা বা যোগ করা যায়। Flink API বেশ কিছু Transformation প্রদান করে, যেমন:

  • Map: প্রতিটি এলিমেন্টে পরিবর্তন আনা হয়।
  • Filter: নির্দিষ্ট শর্তের উপর ভিত্তি করে ডাটা ফিল্টার করা হয়।
  • KeyBy: ডাটাকে কী এর ভিত্তিতে গ্রুপ করা হয়।
  • Reduce: গ্রুপ করা ডাটার উপর অ্যাগ্রিগেট অপারেশন (যেমন, যোগ, গড়) করা হয়।

Example:

DataStream<String> stream = env.readTextFile("path/to/your/file.txt");
DataStream<String> filteredStream = stream
    .filter(line -> line.contains("Flink"))
    .map(line -> line.toUpperCase());

৩. Sink

Sink হলো Flink পাইপলাইনের শেষ কম্পোনেন্ট, যা প্রসেস করা ডাটাকে কোথাও স্টোর বা প্রকাশ করে। Sink কম্পোনেন্ট ডাটাকে বিভিন্ন জায়গায় লেখার জন্য ব্যবহার করা হয়, যেমন:

  • File System: ডাটা ফাইল আকারে সেভ করা যায়।
  • Kafka: প্রসেস করা ডাটাকে Kafka টপিকে পাঠানো হয়।
  • Database: বিভিন্ন ডাটাবেসে ডাটা ইনসার্ট করা হয়।
  • Console: ডাটা আউটপুট হিসেবে কনসোলে প্রিন্ট করা হয়।

Example:

filteredStream.writeAsText("path/to/output/file.txt");

সংক্ষেপে

Flink API-তে ডাটা স্ট্রিম প্রসেসিং সাধারণত তিনটি ধাপের মাধ্যমে হয়:

  1. Source থেকে ডাটা গ্রহণ করা।
  2. Transformation-এর মাধ্যমে ডাটাকে প্রক্রিয়াজাত করা।
  3. Sink-এ প্রক্রিয়াজাত ডাটা পাঠানো।

এই তিনটি কম্পোনেন্ট ব্যবহার করে একটি সম্পূর্ণ Flink ডাটা স্ট্রিমিং অ্যাপ্লিকেশন তৈরি করা হয়।

Flink DataStream API ব্যবহার করে স্ট্রিম প্রসেসিং করতে পারেন। এটি সাধারণত real-time data প্রসেসিংয়ের জন্য ব্যবহৃত হয়। নিচে একটি উদাহরণ দিয়ে দেখানো হয়েছে যেখানে একটি DataStream থেকে ডেটা পড়ে এবং কিছু প্রসেসিং করে আউটপুট দেওয়া হয়েছে।

এই উদাহরণে, আমরা একটি socket থেকে ডেটা পড়ব এবং প্রতি লাইনের প্রতিটি word এর সংখ্যা গণনা করব।

Maven ডিপেন্ডেন্সি (pom.xml)

প্রথমে আপনাকে Maven প্রোজেক্টে Flink এর ডিপেন্ডেন্সি যুক্ত করতে হবে। নিচের কোডটি আপনার pom.xml ফাইলে যুক্ত করুন:

<dependencies>
    <!-- Flink Core Dependency -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java_2.11</artifactId>
        <version>1.15.0</version> <!-- Flink এর ভার্সন -->
    </dependency>
</dependencies>

Flink DataStream উদাহরণ

নিচের উদাহরণে, আমরা Flink এর মাধ্যমে একটি socket থেকে ডেটা পড়ব এবং word count করব। এটি একটি সাধারণ স্ট্রিম প্রসেসিং উদাহরণ।

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;

public class FlinkWordCount {

    public static void main(String[] args) throws Exception {
        // Execution Environment তৈরি করুন
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // DataStream তৈরি করে socket থেকে ডেটা পড়ুন (hostname: localhost, port: 9999)
        DataStream<String> text = env.socketTextStream("localhost", 9999);

        // প্রতিটি লাইনের word গুলোকে আলাদা করে গণনা করুন
        DataStream<Tuple2<String, Integer>> wordCounts = text
            .flatMap(new Tokenizer())
            .keyBy(value -> value.f0)
            .sum(1);

        // আউটপুট প্রিন্ট করুন
        wordCounts.print();

        // Execution শুরু করুন
        env.execute("Socket WordCount Example");
    }

    // Tokenizer class - word গুলোকে আলাদা করে এবং তাদের একটি count সহ output দেয়
    public static final class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
        @Override
        public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
            // প্রতিটি লাইনের word গুলো স্পেস দিয়ে আলাদা করুন
            String[] tokens = value.toLowerCase().split("\\W+");

            // প্রতিটি word কে (word, 1) টুপল হিসেবে প্রেরণ করুন
            for (String token : tokens) {
                if (token.length() > 0) {
                    out.collect(new Tuple2<>(token, 1));
                }
            }
        }
    }
}

কীভাবে চালাবেন:

  1. টার্মিনালে nc -lk 9999 কমান্ডটি রান করুন (যাতে আপনার socket input পাওয়া যায়)।
  2. তারপরে, Flink প্রোজেক্টটি রান করুন। এটি আপনার socket থেকে ইনপুট পড়বে এবং word count শুরু করবে।
  3. আপনি টার্মিনালে কোনো word টাইপ করলে Flink সেই word গুলোর count করে প্রিন্ট করবে।

কোডের ব্যাখ্যা:

  1. Execution Environment: StreamExecutionEnvironment Flink এর স্ট্রিম প্রসেসিংয়ের execution environment তৈরি করে।
  2. DataStream: socket থেকে লাইভ ডেটা পড়া হয় এবং DataStream হিসেবে save করা হয়।
  3. FlatMap: flatMap function ব্যবহার করে প্রতিটি লাইনের word গুলো আলাদা করে এবং তাদের একটি টুপল (word, 1) আকারে return করে।
  4. KeyBy এবং Sum: একই word গুলোকে একত্রিত করে এবং তাদের সংখ্যাগুলো যোগ করে।
  5. print(): আউটপুট কনসোলে প্রিন্ট করে।

এই উদাহরণটি আপনাকে Flink DataStream এর একটি সাধারণ ধারণা দেবে।

Promotion